package com.mkvld.appietijdenv2.data;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import com.mkvld.appietijdenv2.R;


public class Break implements Serializable {
	private static final long serialVersionUID = 6316104671061641198L;
	private BreakType type;
	private double time;
	public Break(BreakType type, double time) {
		this.type = type;
		this.time = time;
	}
	
	public void setType(BreakType type) {
		this.type = type;
	}
	
	public int getMin() {
		return type.getMin();
	}
	
	public boolean isPayed() {
		return type.isPayed();
	}
	
	public double getTime() {
		return time;
	}
	
	public boolean isDinner() {
		return type == BreakType.DINNER;
	}
	
	public boolean isLunchWhole() {
		return type == BreakType.LUNCH_WHOLE;
	}
	
	public int getResourceId() {
		return type.getResourceId();
	}
	
	public static List<Break> getBreaks(double start, double end) {
		List<Break> breaks = new ArrayList<Break>();
		double time = start + 2;
		int dinner = -1;
		int lunch = -1;
		int breakTime = 0;
		int unpayedBreakTime = 0;
		while (end - time >= 2) {
			Break aBreak = new Break(getTypePauze(time), time);
			breakTime += aBreak.getMin();
			if (!aBreak.isPayed())
				unpayedBreakTime += aBreak.getMin();
			if (aBreak.isDinner())
				dinner = breaks.size();
			if (aBreak.isLunchWhole())
				lunch = breaks.size();
			breaks.add(aBreak);
			time += 2f;
			if (!aBreak.isPayed()) {
				time += (double)aBreak.getMin() / 60f;
			}
		}
		
		double werktijd = (end - start) - (double)unpayedBreakTime / 60f;
		
		if (werktijd > 4.5f && end > 19f && dinner == -1) {
			breaks.get(breaks.size() - 1).setType(BreakType.DINNER);
			dinner = breaks.size() - 1;
		}
		
		if (lunch >= 0 && (dinner >= 0 || werktijd < 6f))
			breaks.get(lunch).setType(BreakType.LUNCH_HALF);
		
		if (werktijd > 5.5f && breakTime < 30) {
			while (breaks.size() > 1)
				breaks.remove(breaks.size() - 1);
			breaks.get(0).setType(BreakType.LUNCH_HALF);
		}
		
		// hack because Albert Heijn does not calculate breaks according to CAO
		if (start == 9 && end >= 13 && end < 14) {
			breaks.clear();
			breaks.add(new Break(BreakType.COFFEE, 11));
		}
		return breaks;
	}

	public static BreakType getTypePauze(double time) {
		if ( time < 3f)
			return BreakType.COFFEE;
		else if (time < 5f)
			return BreakType.BREAKFAST;
		else if (time < 7f)
			return BreakType.COFFEE;
		else if (time < 9f)
			return BreakType.BREAKFAST;
		else if (time < 11f)
			return BreakType.COFFEE;
		else if (time < 14f)
			return BreakType.LUNCH_WHOLE;
		else if (time < 17f)
			return BreakType.COFFEE;
		else if (time < 19f)
			return BreakType.DINNER;
		else
			return BreakType.COFFEE;
	}
	
	public static enum BreakType {
		
		COFFEE {
			@Override
			public int getMin() {
				return 10;
			}
			@Override
			public boolean isPayed() {
				return true;
			}
			@Override
			public int getResourceId() {
				return R.string.br_coffee;
			}
		},
		BREAKFAST {
			@Override
			public int getMin() {
				return 15;
			}
			@Override
			public boolean isPayed() {
				return false;
			}
			@Override
			public int getResourceId() {
				return R.string.br_breakfast;
			}
		},
		LUNCH_HALF {
			@Override
			public int getMin() {
				return 30;
			}
			@Override
			public boolean isPayed() {
				return false;
			}
			@Override
			public int getResourceId() {
				return R.string.br_lunch_half;
			}
		},
		LUNCH_WHOLE {
			@Override
			public int getMin() {
				return 60;
			}
			@Override
			public boolean isPayed() {
				return false;
			}
			@Override
			public int getResourceId() {
				return R.string.br_lunch_whole;
			}
		},
		DINNER {
			@Override
			public int getMin() {
				return 30;
			}
			@Override
			public boolean isPayed() {
				return false;
			}
			@Override
			public int getResourceId() {
				return R.string.br_dinner;
			}
		};
		public abstract int getMin();
		public abstract int getResourceId();
		public abstract boolean isPayed();
	}
}
